package com.mars.foodserver.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mars.foodserver.constant.Constant;
import com.mars.foodserver.constant.NumberConstant;
import com.mars.foodserver.entity.FoodType;
import com.mars.foodserver.entity.User;
import com.mars.foodserver.exception.WorkException;
import com.mars.foodserver.mapper.UserMapper;
import com.mars.foodserver.request.UserRequest;
import com.mars.foodserver.request.WeixinUserRequest;
import com.mars.foodserver.response.UserResponse;
import com.mars.foodserver.response.base.PageInfo;
import com.mars.foodserver.service.IUserService;
import com.mars.foodserver.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Objects;


/**
 * User 实现层
 *
 * @Author wq
 * @Date 2021-03-16
 **/
@Service
@Transactional(rollbackFor = RuntimeException.class)
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Resource
    private TokenUtils tokenUtils;

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private WeixinUtils weixinUtils;


    @Override
    public PageInfo<User> page(UserRequest request) {

        IPage<User> page = new Page<>(request.getPageNumber(), request.getPageSize());
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        List<User> records = baseMapper.selectPage(page, wrapper).getRecords();
        if (!CollectionUtils.isEmpty(records)) {
            return new PageInfo<>(page.getTotal(), records);
        }
        return null;
    }

    @Override
    public void updateStatus(Integer userId) {
        User user = baseMapper.selectById(userId);
        if (Objects.isNull(user)) {
            throw new WorkException("用户不存在");
        }
        user.setStatus(2);
        updateById(user);
    }

    @Override
    public void logout(HttpServletRequest request) {
        tokenUtils.logout(request);
    }

    @Override
    public String loginByWeixin(WeixinUserRequest request) {
        log.warn("登录传入的参数为: " + request.toString());
        User selectOne = baseMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getOpenId, request.getOpenId()));
        if (Objects.isNull(selectOne)) {
            //注册
            User user = createUser(request, request.getOpenId());
            long expireTime = GeneratorUtil.generateExpireTime(Constant.CONST_ONE_MONTH);
            //登录成功创建令牌
            String token = JwtUtil.createUserToken(user, expireTime);
            redisUtils.hset(Constant.USER_TOKEN_MAP, user.getId().toString(), "" + expireTime);
            return token;
        } else {
            if (selectOne.getStatus() == 2) {
                throw new WorkException("该用户已注销");
            }
            long expireTime = GeneratorUtil.generateExpireTime(Constant.CONST_ONE_MONTH);
            //登录成功创建令牌
            String token = JwtUtil.createUserToken(selectOne, expireTime);
            redisUtils.hset(Constant.USER_TOKEN_MAP, selectOne.getId().toString(), "" + expireTime);
            return token;
        }
    }

    @Override
    public User selectById(Integer userId) {

        return baseMapper.selectById(userId);
    }

    /**
     * 保存微信用户
     *
     * @param request 请求参数
     * @param openId  openId
     */
    private User createUser(WeixinUserRequest request, String openId) {
        User user = new User();
        user.setOpenId(openId);
        user.setNickname(request.getNickname());
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());
        user.setStatus(NumberConstant.ONE);
        user.setGender(request.getGender());
        user.setAvatar(request.getWxAvatar());
        save(user);
        return user;
    }
}